package com.sailing.xjpb.ipaas.client.core.repository;

import com.sailing.xjpb.common.SailingAssert;
import com.sailing.xjpb.common.exception.IpaasClientException;
import com.sailing.xjpb.common.web.ResponseCode;
import com.sailing.xjpb.ipaas.client.core.IpaasHttpClient;
import com.sailing.xjpb.ipaas.client.entity.dto.OrgParamsDTO;
import com.sailing.xjpb.ipaas.client.entity.dto.SipOrganizationDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.web.client.ResourceAccessException;

import java.util.*;

/**
 * 查询组织相关的接口
 *
 * @author YaoWei
 */
public class SipOrganizationRepository {

    private static final String EXT10 = "ext10";

    /**
     * 查询扩展字段10
     */
    private static final String FIND_ORG_BY_PARAMS = "/external-interface/rmAuca/findOrgByParams";
    /**
     * 注入参数 orgCode
     */
    private static final String ORG_CODE_PARAM = "orgCode";
    @Autowired
    private IpaasHttpClient ipaasHttpClient;

    /**
     * 根据父ID查询下级组织机构数据
     *
     * @param parentId 上级组织ID
     */
    public List<SipOrganizationDTO> findByParentId(String parentId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("parentId", parentId);
        String requestURI = "/external-interface/rmAuca/findChildOrgByParentId/{parentId}";
        String url = getRequestUrl(requestURI);
        return this.getOrganizationList(url, paramMap);
    }

    /**
     * 根据orgId查找包括当前组织在内的所有下级组织
     *
     * @param orgId     组织机构ID
     * @param existUser 是否只查询有用户的组织
     * @author YaoWei
     * createDate 2020年10月30日 下午5:13:20
     */
    public List<SipOrganizationDTO> findConSelfByOrgId(String orgId, boolean existUser) {
        Map<String, Object> paramMap = getOrgIdParamsMap(orgId);
        paramMap.put("existUser", existUser);
        String requestURI = "/external-interface/rmAuca/findConSelfByOrgID/{orgId}?existUser={existUser}";
        String url = getRequestUrl(requestURI);
        return this.getOrganizationList(url, paramMap);
    }

    /**
     * 根据orgId查找包括当前组织在内的所有下级组织
     *
     * @param orgId 组织机构ID
     * @author YaoWei
     * createDate 2020年10月30日 下午5:13:20
     */
    public List<SipOrganizationDTO> findConSelfByOrgId(String orgId) {
        return findConSelfByOrgId(orgId, false);
    }

    /**
     * 根据组织CODE查询组织机构数据
     *
     * @param orgCode 组织机构编码
     */
    public SipOrganizationDTO findByOrgCode(String orgCode) {
        Map<String, Object> paramMap = new HashMap<>(1);
        paramMap.put(ORG_CODE_PARAM, orgCode);
        String requestURI = "/external-interface/rmAuca/findByOrgCode/{orgCode}";
        String url = getRequestUrl(requestURI);
        List<SipOrganizationDTO> response = this.getOrganizationList(url, paramMap);
        SailingAssert.notEmpty(response, "未查询到组织机构编码【" + orgCode + "】对应的组织机构信息！");
        return response.get(0);
    }

    /**
     * ipaas 并发适配接口
     * 根据组织CODE查询组织机构数据
     *
     * @param orgCode 组织机构编码
     */
    public SipOrganizationDTO findByOrgCodeV1(String orgCode) {
        Map<String, Object> paramMap = new HashMap<>(1);
        paramMap.put(ORG_CODE_PARAM, orgCode);
        String requestURI = "/api/v1/org/findByCode/{orgCode}";
        String url = getRequestUrl(requestURI);
        List<SipOrganizationDTO> response = this.getOrganizationListV1(url, paramMap);
        SailingAssert.notEmpty(response, "未查询到组织机构编码【" + orgCode + "】对应的组织机构信息！");
        return response.get(0);
    }

    /**
     * 根据组织机构名称查询所有组织机构数据
     *
     * @param orgName 组织机构名称
     * @param type    组织机构类型
     * @author YaoWei
     * createDate 2020年10月30日 下午5:14:31
     */
    public List<SipOrganizationDTO> findByOrgNameAndEXT10(String orgName, String type) {
        OrgParamsDTO orgParamsDTOOrgName = new OrgParamsDTO();
        orgParamsDTOOrgName.setFieldName(EXT10);
        orgParamsDTOOrgName.setOperator("EQ");
        orgParamsDTOOrgName.setValue(type);
        OrgParamsDTO orgParamsDTOType = new OrgParamsDTO();
        orgParamsDTOType.setFieldName("orgName");
        orgParamsDTOType.setOperator("LIKE");
        orgParamsDTOType.setValue(orgName);
        String url = getRequestUrl(FIND_ORG_BY_PARAMS);
        List<OrgParamsDTO> list = Arrays.asList(orgParamsDTOOrgName, orgParamsDTOType);
        return this.postOrganizationList(url, list);
    }

    /**
     * 根据OrgCode和EXT10 查询组织机构数据
     *
     * @param orgCode 组织机构代码
     * @param type    组织机构类型
     * @author YaoWei
     * createDate 2020年10月30日 下午5:15:10
     */
    public List<SipOrganizationDTO> findByOrgCodeAndEXT10(String orgCode, String type) {
        OrgParamsDTO orgParamsDTOOrgName = new OrgParamsDTO();
        orgParamsDTOOrgName.setFieldName(EXT10);
        orgParamsDTOOrgName.setOperator("EQ");
        orgParamsDTOOrgName.setValue(type);
        OrgParamsDTO orgParamsDTOType = new OrgParamsDTO();
        orgParamsDTOType.setFieldName(ORG_CODE_PARAM);
        orgParamsDTOType.setOperator("EQ");
        orgParamsDTOType.setValue(orgCode);
        String url = getRequestUrl(FIND_ORG_BY_PARAMS);
        List<OrgParamsDTO> list = Arrays.asList(orgParamsDTOOrgName, orgParamsDTOType);
        return this.postOrganizationList(url, list);
    }

    /**
     * 根据组织orgId查询组织机构数据
     *
     * @param orgId 组织ID
     */
    public SipOrganizationDTO findByOrgId(String orgId) {
        Map<String, Object> paramMap = getOrgIdParamsMap(orgId);
        String requestURI = "/external-interface/rmAuca/findOrg/{orgId}";
        String url = getRequestUrl(requestURI);
        return this.getOrganization(url, paramMap);
    }

    /**
     * 根据组织orgId查询直属上级组织机构数据
     *
     * @param orgId 组织ID
     * @return 直属上级组织机构数据
     */
    public SipOrganizationDTO findParent(String orgId) {
        SipOrganizationDTO organizationDTO = findByOrgId(orgId);
        if (organizationDTO == null) {
            return null;
        }
        return findByOrgId(organizationDTO.getParentId());
    }

    /**
     * 查询所有组织机构数据
     */
    public List<SipOrganizationDTO> findAll() {
        String requestURI = "/external-interface/rmAuca/findAll";
        String url = getRequestUrl(requestURI);
        return this.getOrganizationList(url);
    }

    /**
     * 根据userId查询组织机构数据
     *
     * @param userId sip用户主键
     */
    public List<SipOrganizationDTO> findByUserId(String userId) {
        String requestURI = "/external-interface/rmAuca/queryOrgInfoByUserId?userId=" + userId;
        String url = getRequestUrl(requestURI);
        return this.getOrganizationList(url);
    }

    /**
     * 根据EXT10查询组织机构数据
     *
     * @param level 组织机构层级
     * @author YaoWei
     * createDate 2020年10月30日 下午5:16:16
     */
    public List<SipOrganizationDTO> findOrgByLevel(String level) {
        OrgParamsDTO orgParamsDTO = new OrgParamsDTO();
        orgParamsDTO.setFieldName(EXT10);
        orgParamsDTO.setOperator("EQ");
        orgParamsDTO.setValue(level);
        List<OrgParamsDTO> list = Collections.singletonList(orgParamsDTO);
        String url = getRequestUrl(FIND_ORG_BY_PARAMS);
        return this.postOrganizationList(url, list);
    }

    /**
     * 通过组织id查找所有父级组织机构信息
     *
     * @param orgId 组织机构ID
     * @author YaoWei
     * createDate 2020年10月30日 下午5:16:57
     */
    public List<SipOrganizationDTO> findAllParentOrg(String orgId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orgId", orgId);
        String requestURI = "/external-interface/rmAuca/findUpAllOrg/{orgId}";
        String url = getRequestUrl(requestURI);
        return this.getOrganizationList(url, paramMap);
    }

    /**
     * 根据组织机构名称查询所有组织机构数据
     *
     * @param orgParams 查询参数
     * @author YaoWei createDate 2020年10月30日 下午5:14:31
     */
    public List<SipOrganizationDTO> findByOrgParams(OrgParamsDTO... orgParams) {
        String url = getRequestUrl(FIND_ORG_BY_PARAMS);
        List<OrgParamsDTO> list = Arrays.asList(orgParams);
        return this.postOrganizationList(url, list);
    }

    private SipOrganizationDTO getOrganization(String url, Map<String, Object> params) {
        try {
            return ipaasHttpClient.exchange(url, HttpMethod.GET, SipOrganizationDTO.class, params);
        } catch (ResourceAccessException e) {
            throw parseException(e);
        }
    }

    private List<SipOrganizationDTO> getOrganizationList(String url) {
        return this.getOrganizationList(url, new HashMap<>());
    }

    private List<SipOrganizationDTO> getOrganizationList(String url, Map<String, Object> params) {
        try {
            return ipaasHttpClient.list(url, HttpMethod.GET, SipOrganizationDTO.class, params);
        } catch (ResourceAccessException e) {
            throw parseException(e);
        }
    }

    private List<SipOrganizationDTO> getOrganizationListV1(String url, Map<String, Object> params) {
        try {
            return ipaasHttpClient.listV1(url, HttpMethod.GET, SipOrganizationDTO.class, params);
        } catch (ResourceAccessException e) {
            throw parseException(e);
        }
    }

    private List<SipOrganizationDTO> postOrganizationList(String url, Object body) {
        try {
            return ipaasHttpClient.list(url, HttpMethod.POST, SipOrganizationDTO.class, body);
        } catch (ResourceAccessException e) {
            throw parseException(e);
        }
    }

    private String getRequestUrl(String requestURI) {
        return requestURI;
    }

    private Map<String, Object> getOrgIdParamsMap(String orgId) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("orgId", orgId);
        return paramMap;
    }

    private IpaasClientException parseException(Exception e) {
        return new IpaasClientException(ResponseCode.T_4000, "ipaas接口连接异常！", e);
    }


}